﻿using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;

// 添加别名解决冲突
using HtmlDocument = HtmlAgilityPack.HtmlDocument;

namespace YGBookmark.Utils
{
    /// <summary>
    /// HTTP请求帮助类，提供网页内容获取和编码自动检测功能
    /// </summary>
    public static class HttpHelper
    {
        /// <summary>
        /// 获取指定URL的HTML内容（支持自动编码检测）
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="timeoutSeconds">超时时间（秒）</param>
        /// <returns>解码后的HTML内容</returns>
        public static async Task<string> GetHtmlContentAsync(string url, int timeoutSeconds = 30)
        {
            using var handler = new HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };

            using var httpClient = new HttpClient(handler);
            httpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);
            httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

            try
            {
                var response = await httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();

                var contentType = response.Content.Headers.ContentType;
                var bytes = await response.Content.ReadAsByteArrayAsync();

                // 分阶段编码检测
                var encoding = GetEncodingFromContentType(contentType) ?? Encoding.UTF8;
                var html = encoding.GetString(bytes);
                var detectedEncoding = DetectEncodingFromHtml(html);

                return detectedEncoding != null && !Equals(detectedEncoding, encoding)
                    ? detectedEncoding.GetString(bytes)
                    : html;
            }
            catch (Exception ex)
            {
                throw new HttpRequestException($"获取网页内容失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 从Content-Type头获取编码
        /// </summary>
        private static Encoding GetEncodingFromContentType(MediaTypeHeaderValue contentType)
        {
            try
            {
                return contentType?.CharSet != null
                    ? Encoding.GetEncoding(contentType.CharSet)
                    : null;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 从HTML内容检测编码（使用HtmlAgilityPack）
        /// </summary>
        private static Encoding DetectEncodingFromHtml(string html)
        {
            var doc = new HtmlDocument();
            try { doc.LoadHtml(html); } catch { return null; }

            // 检测<meta charset>标签
            var metaCharset = doc.DocumentNode.SelectSingleNode("//meta[@charset]");
            if (metaCharset != null)
            {
                var charset = metaCharset.GetAttributeValue("charset", null);
                if (!string.IsNullOrWhiteSpace(charset))
                {
                    try { return Encoding.GetEncoding(charset); }
                    catch { /* 忽略无效编码 */ }
                }
            }

            // 检测http-equiv声明
            var metaHttpEquiv = doc.DocumentNode.SelectSingleNode("//meta[@http-equiv='Content-Type']");
            if (metaHttpEquiv != null)
            {
                var content = metaHttpEquiv.GetAttributeValue("content", "");
                foreach (var part in content.Split(';'))
                {
                    var keyValue = part.Trim().Split(new[] { '=' }, 2);
                    if (keyValue.Length == 2 &&
                        keyValue[0].Trim().Equals("charset", StringComparison.OrdinalIgnoreCase))
                    {
                        try { return Encoding.GetEncoding(keyValue[1].Trim()); }
                        catch { /* 忽略无效编码 */ }
                    }
                }
            }

            return null;
        }
    }
}